home *** CD-ROM | disk | FTP | other *** search
/ Aminet 22 / Aminet 22 (1997)(GTI - Schatztruhe)[!][Dec 1997].iso / Aminet / dev / e / amigae33a.lha / E_v3.3a / Src.lha / Src / Utils / Ag2Txt / Ag2Txt.c < prev   
C/C++ Source or Header  |  1994-08-16  |  7KB  |  368 lines

  1. /* AmigaGuide to Text converter (v2). Copyright (c) 1994, Jason R. Hulance */
  2. /* C version. Restricted use of ANSI codes, so they work on Xterms etc.    */
  3. /* Should compile easily (using gcc, say):                                 */
  4. /*    gcc -O2 -o ag2txt ag2txt.c                                           */
  5.  
  6. #include<stdio.h>
  7. #include<ctype.h>
  8.  
  9. typedef enum { N_INIT, N_OUT, N_IN, NODE_STATES } NODE;
  10. typedef enum { L_INIT, L_QUOTED, L_SPACED, LINE_STATES } LINE;
  11. typedef enum { A_INIT, A_AT, A_BRAC, A_IGNORE, A_END, AT_STATES } AT;
  12.  
  13. #define MAX_LINE_LEN (1024)
  14. #define MAX_WIDTH    (120)
  15. #define CMP_EQUAL    (0)
  16. #define CMP_UNEQUAL  (1)
  17.  
  18. #define TRUE  (0==0)
  19. #define FALSE (1==0)
  20.  
  21. char in[MAX_LINE_LEN];
  22. FILE *outh=NULL;
  23.  
  24. typedef enum {BOLD, ITALIC, F_LINK, TITLE, HIGHLIGHT, OTHER} FONT;
  25.  
  26. void write_ansi(FONT type, int on)
  27. {
  28.   /*    BOLD      ITALIC       F_LINK     TITLE    HIGHLIGHT    OTHER */
  29.   if(on) {
  30.     static char *ansi[] = {
  31.       "\033[1m", "\033[1m",  "\033[1m", "\033[7m", "\033[1m", "\033[1m" };
  32.     fputs(ansi[type], outh);
  33.   }
  34.   else {
  35.     static char *ansi[] = {
  36.       "\033[0m", "\033[0m", "\033[0m", "\033[0m", "\033[0m", "\033[0m" };
  37.     fputs(ansi[type], outh);
  38.   }
  39. }
  40.  
  41. int Stricmp(char *s, char *t)
  42. {
  43.   while(*s && *t) {
  44.     if(toupper(*s) != *t)
  45.       return CMP_UNEQUAL;
  46.     s++, t++;
  47.   }
  48.   return (*s || *t) ? CMP_UNEQUAL : CMP_EQUAL;
  49. }
  50.  
  51. int Strnicmp(char *s, char *t)
  52. {
  53.   while(*s && *t) {
  54.     if(toupper(*s) != *t)
  55.       return CMP_UNEQUAL;
  56.     s++, t++;
  57.   }
  58.   return (*t) ? CMP_UNEQUAL : CMP_EQUAL;
  59. }
  60.  
  61. void error(char *msg, int err)
  62. {
  63.   fputs(msg, stderr);
  64.   exit(err);
  65. }
  66.  
  67. char *get_word(char **line, int *chkbrac)
  68. {
  69.   LINE status=L_INIT;
  70.   char *t=NULL, *to;
  71.   int noword=TRUE, special=FALSE;
  72.  
  73.   if(line==NULL || *line==NULL)
  74.     return NULL;
  75.   to=*line;
  76.   while(**line && noword) {
  77.     if(to != *line) *to = **line;
  78.     switch(**line) {
  79.     case '"':
  80.       if(special)
  81.     to++;
  82.       else {
  83.     switch(status) {
  84.     case L_INIT:
  85.       status=L_QUOTED;
  86.       t=(*line)+1;
  87.       to++;
  88.       break;
  89.     case L_QUOTED:
  90.       *to='\0';
  91.       noword=FALSE;
  92.       break;
  93.     default:
  94.       to++;
  95.       break;
  96.     }
  97.       }
  98.       break;
  99.     case '\n': case '\t': case ' ':
  100.       if(status==L_SPACED) {
  101.         *to='\0';
  102.         noword=FALSE;
  103.       }
  104.       else
  105.     to++;
  106.       break;
  107.     default:
  108.       if(chkbrac && **line=='}') {
  109.         *to='\0';
  110.         noword=FALSE;
  111.         *chkbrac=TRUE;
  112.       }
  113.       else {
  114.     if(status==L_INIT) {
  115.           t=*line;
  116.           status=L_SPACED;
  117.     }
  118.     to++;
  119.       }
  120.       break;
  121.     }
  122.     if(special)
  123.       special=FALSE;
  124.     else if(**line=='\\') {
  125.       special=TRUE;
  126.       to--;
  127.     }
  128.     (*line)++;
  129.   }
  130.   return t;
  131. }
  132.  
  133. int parse_at_line(char **line)
  134. {
  135.   char *first, *second, *third;
  136.   int gotbrac=FALSE, i=0, on=TRUE;
  137.   char c;
  138.  
  139.   first=get_word(line, &gotbrac);
  140.   if(first && *first) {
  141.     i=1;
  142.     if(gotbrac==FALSE) {
  143.       second=get_word(line, &gotbrac);
  144.       if(second && *second) {
  145.         i=2;
  146.         if(gotbrac==FALSE) {
  147.           third=get_word(line, &gotbrac);
  148.           if(third && *third)
  149.         i=3;
  150.     }
  151.       }
  152.     }
  153.   }
  154.   switch(i) {
  155.   case 1:
  156.     if(toupper(*first)=='U') {
  157.       on=FALSE;
  158.       first++;
  159.     }
  160.     c=toupper(*first);
  161.     switch(c) {
  162.     case 'B':
  163.       write_ansi(BOLD, on);
  164.       break;
  165.     case 'I':
  166.       write_ansi(ITALIC, on);
  167.       break;
  168.     }
  169.     break;
  170.   case 2:
  171.     if(Stricmp(first, "FG")==CMP_EQUAL) {
  172.       if(Stricmp(second, "HIGHLIGHT")==CMP_EQUAL)
  173.         write_ansi(HIGHLIGHT, TRUE);
  174.       else if(Stricmp(second, "TEXT")==CMP_EQUAL)
  175.         write_ansi(HIGHLIGHT, FALSE);
  176.     }
  177.     else if(Stricmp(second, "CLOSE")==CMP_EQUAL ||
  178.         Stricmp(second, "QUIT")==CMP_EQUAL) {
  179.       write_ansi(OTHER, TRUE);
  180.       fputs(first, outh);
  181.       write_ansi(OTHER, FALSE);
  182.     }
  183.     break;
  184.   case 3:
  185.     if(Stricmp(second, "LINK")==CMP_EQUAL ||
  186.        Stricmp(second, "ALINK")==CMP_EQUAL) {
  187.       write_ansi(F_LINK, TRUE);
  188.       fputs(first, outh);
  189.       write_ansi(F_LINK, FALSE);
  190.     }
  191.     else {
  192.       write_ansi(OTHER, TRUE);
  193.       fputs(first, outh);
  194.       write_ansi(OTHER, FALSE);
  195.     }
  196.     break;
  197.   }
  198.   return gotbrac;
  199. }
  200.  
  201. void parse_node_line(char *line, char *title)
  202. {
  203.   char *first, *second;
  204.   first=get_word(&line, NULL);
  205.   second=get_word(&line, NULL);
  206.   if(first && *first) {
  207.     if(second && *second)
  208.       strcpy(title, second);
  209.     else
  210.       strcpy(title, first);
  211.   }
  212. }
  213.  
  214. void parse_title_line(char *line, char *title)
  215. {
  216.   char *first;
  217.   first=get_word(&line, NULL);
  218.   if(first && *first)
  219.     strcpy(title, first);
  220. }
  221.  
  222. void statecopy(AT state)
  223. {
  224.   switch(state) {
  225.   case A_IGNORE:
  226.     fputc('\\', outh);
  227.     break;
  228.   case A_AT:
  229.     fputc('@', outh);
  230.     break;
  231.   case A_BRAC:
  232.     fputs("@{", outh);
  233.     break;
  234.   }
  235. }
  236.  
  237. void output(char *line)
  238. {
  239.   AT status=A_INIT;
  240.   int gotbrac;
  241.   char c;
  242.  
  243.   if(line[0]=='@' && line[1]!='{')
  244.     return;
  245.   while(c=*line) {
  246.     switch(c) {
  247.     case '\\':
  248.       if(status==A_INIT)
  249.         status=A_IGNORE;
  250.       else {
  251.         statecopy(status);
  252.         fputc(c, outh);
  253.         status=A_INIT;
  254.       }
  255.       line++;
  256.       break;
  257.     case '@':
  258.       if(status==A_INIT)
  259.         status=A_AT;
  260.       else {
  261.         if(status!=A_IGNORE) statecopy(status);
  262.         fputc(c, outh);
  263.         status=A_INIT;
  264.       }
  265.       line++;
  266.       break;
  267.     case '{':
  268.       if(status==A_AT)
  269.         status=A_BRAC;
  270.       else {
  271.         statecopy(status);
  272.         fputc(c, outh);
  273.         status=A_INIT;
  274.       }
  275.       line++;
  276.       break;
  277.     case '}':
  278.       switch(status) {
  279.       case A_BRAC: case A_END:
  280.     break;
  281.       default:
  282.         statecopy(status);
  283.         fputc(c, outh);
  284.     break;
  285.       }
  286.       status=A_INIT;
  287.       line++;
  288.       break;
  289.     default:
  290.       switch(status) {
  291.       case A_BRAC:
  292.         gotbrac=parse_at_line(&line);
  293.         status=(gotbrac ? A_INIT : A_END);
  294.     break;
  295.       case A_END:
  296.         line++;
  297.     break;
  298.       default:
  299.         statecopy(status);
  300.         fputc(c, outh);
  301.         status=A_INIT;
  302.         line++;
  303.       }
  304.     }
  305.   }
  306. }
  307.  
  308. void main(int argc, char *argv[])
  309. {
  310.   FILE *fh;
  311.   NODE status=N_INIT;
  312.   char *s, title[MAX_WIDTH];
  313.   int empty=TRUE;
  314.   char *top="\n--------------------------------------" \
  315.             "--------------------------------------\n";
  316.   char *bot="======================================" \
  317.             "======================================\n";
  318.   if(argc<2)
  319.     error("Usage:  ag2txt <infile> [<outfile>]\n", 1);
  320.   if((fh=fopen(argv[1], "r"))==NULL) {
  321.     fprintf(stderr, "\"%s\" ", argv[1]);
  322.     error("could not be opened\n", 2);
  323.   }
  324.   if(argc>2)
  325.     outh=fopen(argv[2], "w");
  326.   if(outh==NULL)
  327.     outh=stdout;
  328.   while(fgets(in, MAX_LINE_LEN, fh)) {
  329.     switch(status) {
  330.     case N_INIT:
  331.       if(Strnicmp(in, "@DATABASE")!=CMP_EQUAL)
  332.         error("Bad AmigaGuide input file\n", 3);
  333.       else
  334.         status=N_OUT;
  335.       break;
  336.     case N_OUT:
  337.       if(Strnicmp(in, "@NODE ")==CMP_EQUAL) {
  338.         status=N_IN;
  339.     parse_node_line(in+6, title);
  340.         empty=TRUE;
  341.       }
  342.       break;
  343.     case N_IN:
  344.       if(empty && Strnicmp(in, "@TITLE")==CMP_EQUAL)
  345.     parse_title_line(in+6, title);
  346.       else if(Strnicmp(in, "@ENDNODE")==CMP_EQUAL) {
  347.         fputs(bot, outh);
  348.     status=N_OUT;
  349.       }
  350.       else {
  351.         s=in;
  352.     while(*s == ' ' || *s == '\t' || *s == '\n') s++;
  353.         if(!(empty && *s=='\0')) {
  354.           if(empty) {
  355.             write_ansi(TITLE, TRUE);
  356.             fputs(title, outh);
  357.             write_ansi(TITLE, FALSE);
  358.             fputs(top, outh);
  359.             empty=FALSE;
  360.       }
  361.           output(in);
  362.     }
  363.       }
  364.       break;
  365.     }
  366.   }
  367. }
  368.